package net.edu_soft.ec.asset.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import net.edu_soft.ec.asset.constant.EduConstant;
import net.edu_soft.ec.asset.mapper.AuditMapper;
import net.edu_soft.ec.asset.pojo.Audit;
import net.edu_soft.ec.asset.pojo.AuditExample;
import net.edu_soft.ec.asset.pojo.Product;
import net.edu_soft.ec.asset.pojo.ResultType;
import net.edu_soft.ec.asset.pojo.bo.AuditBO;
import net.edu_soft.ec.asset.pojo.vo.AuditVO;
import net.edu_soft.ec.asset.service.AuditService;
import net.edu_soft.ec.asset.service.FactoryService;
import net.edu_soft.ec.asset.service.ProductService;
import net.edu_soft.ec.common.exception.OperationException;
import net.edu_soft.ec.common.exception.ParameterException;
import net.edu_soft.ec.common.util.PuingUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AuditServiceImpl implements AuditService {

    @Autowired
    private AuditMapper auditMapper;

    //注入产品业务
    @Autowired
    private ProductService productService;

    //注入厂家业务类
    @Autowired
    private FactoryService factoryService;

    //注入申请业务类


    @Override
    public Audit getAuditBySubAndType(Integer subjectId, Integer type) {
        AuditExample exapmle = new AuditExample();
        AuditExample.Criteria criteria = exapmle.createCriteria();
        //添加主体
        criteria.andSubjectIdEqualTo(subjectId);
        //添加审核类型
        criteria.andTypeEqualTo(type);
        //添加状态
        criteria.andStatusEqualTo(EduConstant.STATUS_ZREO);
        List<Audit> audits = auditMapper.selectByExample(exapmle);
        if (audits.size() > 0) {
            //提取
            return audits.get(0);
        }
        return null;
    }

    @Override
    public int saveAudit(Audit audit) {
        if (audit.getAuditId() != null) {
            throw new OperationException("操作失败，不能添加");
        }
        //校验数据
        checkData(audit);
        //设置状态为0 可用
        audit.setStatus(EduConstant.STATUS_ZREO);
        //查询是否存在
        if (getAuditBySubAndType(audit.getSubjectId(), audit.getType()) != null) {
            throw new OperationException("操作失败，重复添加");
        }
        //添加
        //设置未审核
        audit.setAuditStatus(EduConstant.AUDIT_STATUS_NOT);
        int i = auditMapper.insertSelective(audit);
        if (i == 0) {
            throw new OperationException("删除失败。请检查数据或链接");
        }
        return i;
    }


    @Override
    public int delAuditByIds(String ids, int bool) {
        int i = 0;
        //提取id
        List<Integer> idList = PuingUtil.getNumber(ids);
        //循环修改状态
        for (Integer id : idList) {
            Audit audit = selAuditById(id, bool);
            if (audit == null) {
                throw new OperationException("删除审核失败，参数错误或者该id ："+id+ "对象不存在");
            }
            //设置状态为1 不可用
            audit.setStatus(EduConstant.STATUS_ONE);

            i = auditMapper.updateByPrimaryKeySelective(audit);
            if (i == 0) {
                throw new OperationException("删除失败，内部错误");
            }
        }
        return i;
    }

    @Override
    public PageInfo<AuditVO> findALL(Integer type, Integer auditStatus, Integer pageNum, Integer pageSize) {
        PuingUtil.notNullByInt("审核管理：分页参数有误，不能为空或小于等于0", pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<Audit> auditList = selSubjectIds(type, auditStatus);
        List<Integer> subjectIds = new ArrayList<>();
        //提取id
        if (auditList.size() > 0) {
            for (Audit audit : auditList) {
                subjectIds.add(audit.getSubjectId());
            }
        }
        List<ResultType> resultTypes = null;
        if (subjectIds.size() <= 0) {
            throw new ParameterException("审核管理：审核数据为空");
        }
        if (type == EduConstant.AUDIT_TYPE_PRODUCT && type != null) {
            //产品
            resultTypes = auditMapper.selProNames(subjectIds);
        } else if (type == EduConstant.AUDIT_TYPE_FACTORY && type != null) {
            //厂家
            resultTypes = auditMapper.selFacNames(subjectIds);
        } else if (type == EduConstant.AUDIT_TYPE_APPLY && type != null) {
            //申请
            resultTypes = auditMapper.selApplyNames(subjectIds);
        } else {
            throw new ParameterException("审核管理：审核类型参数错误");
        }
        List<AuditVO> auditVOS = new ArrayList<>();
        if (resultTypes != null) {
            for (int i = 0; i < resultTypes.size(); i++) {
                //判断审核数据的主体id是否等于查询出来的产品/厂家/申请id是否相同
                if (resultTypes.get(i).getId() == auditList.get(i).getSubjectId()) {
                    AuditVO auditVO = new AuditVO();
                    auditVO.setAuditId(auditList.get(i).getAuditId());
                    auditVO.setAuditor(auditList.get(i).getAuditor());
                    auditVO.setType(auditList.get(i).getType());
                    auditVO.setSubjectId(auditList.get(i).getSubjectId());
                    auditVO.setSubjectName(resultTypes.get(i).getType());
                    auditVO.setAuditStatus(auditList.get(i).getAuditStatus());
                    auditVOS.add(auditVO);
                }
            }
        }
        PageInfo<AuditVO> pageInfo = new PageInfo<>(auditVOS);
        return pageInfo;
    }

    @Override
    public int auditOperation(Audit audit) {
        return auditOneOperation(audit);
    }

    @Override
    public int auditALLOperation(String audits) {
        Assert.hasLength(audits,"审核管理：审核信息集合不能为空");
        List<Audit> auditList = JSONObject.parseArray(audits, Audit.class);
        PuingUtil.notNullByList(auditList, "审核管理，审核信息集合为空");
        int code = 0;
        for (Audit audit:auditList) {
            code += auditOneOperation(audit);
        }
        return code;
    }


    /***
     * 根据审核id、用户id、主体id查询审核信息
     * @param id 审核id、用户id、主体id
     * @param bool 鉴别 0为审核、1为主体
     * @return
     */
    private Audit selAuditById(Integer id, int bool) {
        PuingUtil.notNullByZero(id, "审核id不能为空或小于等于0");
        AuditExample exapmle = new AuditExample();
        AuditExample.Criteria criteria = exapmle.createCriteria();
        if (bool == 0) {
            //添加审核id
            criteria.andAuditIdEqualTo(id);
        } else if (bool == 1) {
            criteria.andSubjectIdEqualTo(id);
        } else {
            criteria.andUserInfoIdEqualTo(id);
        }
        //添加状态
        criteria.andStatusEqualTo(EduConstant.STATUS_ZREO);
        List<Audit> audits = auditMapper.selectByExample(exapmle);
        if (audits.size() > 0) {
            return audits.get(0);
        }
        return null;
    }


    /***
     * 校验数据
     * @param audit 审核信息
     * @return
     */
    private Audit checkData(Audit audit) {
        //校验 审核id、主体id、审核类型id、审核人id
        PuingUtil.notNullByInt("参数不能为空或者小于等于0", audit.getSubjectId(), audit.getUserInfoId());
        //校验审核员
        Assert.hasLength(audit.getAuditor(), "审核员名称不能为空");
        //校验审核状态   判断是否为几类待审核、审核中、审核失败
        Assert.isNull(audit.getAuditStatus(), "审核状态不能为空");
        return audit;
    }

    private List<Audit> selSubjectIds(Integer type, Integer auditStatus) {
        List<Integer> subjectIds = new ArrayList<>();
        //判断审核类型和审核状态是否为 0,1,2
        if (type < 0 || type > 2 || type == null || auditStatus < 0 || auditStatus > 2 || auditStatus == null) {
            throw new ParameterException("审核管理：审核参数或者审核类型参数有误");
        }
        AuditExample example = new AuditExample();
        AuditExample.Criteria criteria = example.createCriteria();
        //添加审核状态
        criteria.andAuditStatusEqualTo(auditStatus);
        //添加审核类型
        criteria.andTypeEqualTo(type);
        //添加状态
        criteria.andStatusEqualTo(EduConstant.STATUS_ZREO);
        List<Audit> list = auditMapper.selectByExample(example);
        return list;
    }

    private Integer isAudit(Integer element, Integer[] arr) {
        int s = 0;
        if (element == null) {
            throw new ParameterException("审核管理：参数错误");
        }
        //遍历状态
        for (Integer i : arr) {
            if (element == i) {
                s = 1;
            }
        }
        //存在就返回状态，不存在就抛出异常
        if (s == 1) {
            return element;
        } else {
            throw new ParameterException("审核管理：参数错误");
        }
    }

    private int auditOneOperation(Audit audit){
        int code = 0;
        //判断数据
        if (audit == null) {
            throw new ParameterException("审核管理：审核对象数据参数为空");
        }
        //查询审核信息
        Audit selAudit = selAuditById(audit.getAuditId(), 0);
        //根据审核id查询判断是否存在
        if (selAudit == null) {
            throw new ParameterException("审核管理：审核对象数据参数为空");
        }
        //得到审核状态
        int auditStatus = isAudit(audit.getAuditStatus(), EduConstant.AUDIT_STATUS_ARR);
        //修改审核人id
        selAudit.setUserInfoId(audit.getUserInfoId());
        //修改审核人名字
        selAudit.setAuditor(audit.getAuditor());
        //修改审核状态
        selAudit.setAuditStatus(auditStatus);
        //修改审核信息
        int i = auditMapper.updateByPrimaryKey(selAudit);
        //校验提取审核类型
        int auditType = isAudit(audit.getType(), EduConstant.AUDIT_TYPE_ARR);
        //已审核
        AuditBO auditBO = new AuditBO();
        //传入 0产品/1厂家/2申请
        //类型
        auditBO.setType(auditType);
        //状态为 0 存在
        //主体id
        List<Integer> ids = new ArrayList<>();
        ids.add(audit.getSubjectId());
        auditBO.setSubId(selAudit.getSubjectId());
        if (i == 1) {
            //判断审核状态是否为已审核，已审核则设置产品/厂家/申请的状态为0，其余为1
            if (auditStatus == EduConstant.AUDIT_STATUS_THEN) {
                //已审核,状态为0 可用
                auditBO.setStatus(EduConstant.STATUS_ZREO);
                code = auditMapper.updateSubsStatus(auditBO);
            } else {
                //审核不通过或者审核失败 状态为1 不可用
                auditBO.setStatus(EduConstant.STATUS_ONE);
                code = auditMapper.updateSubsStatus(auditBO);
            }
        }
        return code;
    }
}
